#include "SList.h"

// 链表的打印

void SLTPrint (SLTNode* phead)
{

    assert (phead) ;

    SLTNode* pcur = phead ;

    while (pcur)
    {

        printf ("%d -> " , pcur -> data) ;

        pcur = pcur -> next ;

    }

    printf ("NULL\n") ;

}

// 链表的查找

SLTNode* SLTFind (SLTNode* phead , SLTDataType x)
{

    assert (phead) ;

    SLTNode* pcur = phead ;

    while (pcur)
    {

        if (pcur -> data == x)
        {

            return pcur ;

        }

        pcur = pcur -> next ;

    }

    return NULL ;

}

// 将创建新的节点的函数单独拎出来,方便重复使用

SLTNode* SLTBuyNode (SLTDataType x)
{

    // 根据数据x创建节点

    SLTNode* newnode = (SLTNode*) malloc (sizeof (SLTNode)) ;

    if (newnode == NULL)
    {

        perror ("malloc fail!") ;

        exit (1) ;

    }

    newnode -> data = x ;

    newnode -> next = NULL ;

    return newnode ;

}

// 链表的尾插

void SLTPushBack (SLTNode** pphead , SLTDataType x)
{

    assert (pphead) ;

    SLTNode* newnode = SLTBuyNode (x) ;

    if (*pphead == NULL)
    {

        *pphead = newnode ;

    }

    else
    {

        // 找尾部

        SLTNode* ptail = *pphead ;

        while (ptail -> next)
        {

            ptail = ptail -> next ;
            
        }

        ptail -> next = newnode ;
        
    }

}

// 链表的尾删

void SLTPopBack (SLTNode** pphead)
{

    assert (pphead && *pphead) ;

    if ((*pphead) -> next == NULL)
    {

        free (*pphead) ;

        *pphead = NULL ;

    }

    else
    {

        SLTNode* ptail = *pphead ;

        SLTNode* pcur = NULL ;

        while (ptail -> next)
        {

            pcur = ptail ;

            ptail = ptail -> next ;

        }

        free (ptail) ;

        ptail = NULL ;

        pcur -> next = NULL ;

    }
    
}

// 链表的头插

void SLTPushFront (SLTNode** pphead , SLTDataType x)
{

    assert (pphead) ;

    SLTNode* newnode = SLTBuyNode (x) ;

    // newnode *pphead

    newnode -> next = *pphead ;

    *pphead = newnode ;

}

// 链表的头删

void SLTPopFront (SLTNode** pphead)
{

    assert (pphead && *pphead) ;

    SLTNode* next = (*pphead) -> next ;

    free (*pphead) ;

    *pphead = next ;
    
}

// 在指定位置之前插入数据

void SLTInsert (SLTNode** pphead , SLTNode* pos , SLTDataType x)
{

    assert (pphead && pos) ;

    // 当pos指向第一个节点,是头插

    if (pos == *pphead)
    {

        SLTPushFront (pphead , x) ;
        
    }

    else
    {

        SLTNode* newnode = SLTBuyNode (x) ;

        // 找pos的前一个节点

        SLTNode* prev = *pphead ;

        while (prev -> next != pos)
        {

            prev = prev -> next ;

        }

        // prev --> newnode --> pos

        prev -> next = newnode ;

        newnode -> next = pos ;

    }

}

// 在指定位置之后插入数据

void SLTInsertAfter (SLTNode* pos , SLTDataType x)
{

    assert (pos) ;

    SLTNode* newnode = SLTBuyNode (x) ;

    // pos --> newnode --> pos -> next

    newnode -> next = pos -> next ;

    pos -> next = newnode ;

}

// 删除pos位置的数据

void SLTErase (SLTNode** pphead , SLTNode* pos)
{

    assert (pphead && pos) ;

    // pos是头结点

    if (pos == *pphead)
    {

        SLTPopFront (pphead) ;

    }

    else
    {

        SLTNode* prev = *pphead ;

        while (prev -> next != pos)
        {

            prev = prev -> next ;
            
        }

        prev -> next = pos -> next ;

        free (pos) ;

        pos = NULL ;
        
    }

}

// 删除pos位置之后的节点

void SLTEraseAfter (SLTNode* pos)
{

    assert (pos && pos -> next) ;

    // pos del del -> next 

    SLTNode* del = pos -> next ;

    pos -> next = del -> next ;

    free (del) ;

    del = NULL ;

}

// 销毁链表

void SLTDestory (SLTNode** pphead)
{

    assert (pphead && *pphead) ;

    SLTNode* pcur = *pphead ;

    while (pcur)
    {

        SLTNode* next = pcur -> next ;

        free (pcur) ;

        pcur = next ;

    }

    *pphead = NULL ;
    
}